#!/usr/bin/env node
const readline = require("readline");
const net = require("net");
const EventEmitter = require("events");

// 终端颜色
const colors = {
    reset: "\x1b[0m",
    green: "\x1b[32m",
    red: "\x1b[31m",
    yellow: "\x1b[33m",
    cyan: "\x1b[36m",
    magenta: "\x1b[35m",
    blue: "\x1b[34m",
    white: "\x1b[37m",
    brightRed: "\x1b[91m",
    brightGreen: "\x1b[92m",
    brightYellow: "\x1b[93m",
    brightBlue: "\x1b[94m",
    brightMagenta: "\x1b[95m",
    brightCyan: "\x1b[96m",
};

// 玩家颜色配置
const playerColors = [
    colors.brightGreen,   // 玩家1 - 亮绿色
    colors.brightBlue,    // 玩家2 - 亮蓝色  
    colors.brightYellow,  // 玩家3 - 亮黄色
    colors.brightMagenta, // 玩家4 - 亮紫色
    colors.brightCyan,    // 玩家5 - 亮青色
    colors.brightRed,     // 玩家6 - 亮红色
    colors.white,         // 玩家7 - 白色
    colors.cyan,          // 玩家8 - 青色
];

// 游戏参数
const rows = 20;
const cols = 80;

let snake = [[5, 5]]; // 玩家蛇
let direction = "right";

let aiSnake = [[15, 5]]; // AI蛇
let aiDirection = "up";

let food = []; // 食物
let obstacles = [];
let gameOver = false;

// 初始速度（ms）
const speed = 300;

// 服务器Tick计时器
let lastServerTick = Date.now();
let serverUpdateInterval = 300; // 服务器更新间隔(毫秒)

// 网络游戏配置
let isServer = false;
let isClient = false;
let gameMode = "single"; // single, server, client
let server = null;
let client = null;
let players = new Map(); // playerId -> playerData
let currentPlayerId = "player1";
let gameRoom = new EventEmitter();

// 客户端预测和插值
let clientPrediction = new Map(); // playerId -> predicted position
let lastServerUpdate = Date.now();
let serverTickRate = 100; // 服务器更新频率(ms)
let clientInterpolation = true; // 启用客户端插值

// 玩家生命
let lives = 3;

// 穿墙模式开关
const wrapAround = true;

// 方向映射
const directions = {
    up: [-1, 0],
    down: [1, 0],
    left: [0, -1],
    right: [0, 1],
};

// 网络游戏函数
function createServer(port = 3000) {
    server = net.createServer();
    let connectionId = 0;
    
    server.on('connection', (socket) => {
        const playerId = `player${++connectionId}`;
        // 客户端玩家从索引1开始，避免与服务器玩家颜色重复
        const playerColor = playerColors[connectionId % playerColors.length];
        
        // 设置TCP无延迟
        socket.setNoDelay(true);
        
        players.set(playerId, {
            socket: socket,
            snake: [[5 + connectionId * 3, 5 + connectionId * 2]],
            direction: "right",
            color: playerColor,
            connected: true,
            lastInput: Date.now(),
            inputBuffer: [] // 输入缓冲区
        });
        
        console.log(`玩家 ${playerId} 已连接，颜色索引: ${connectionId}`);
        
        socket.on('data', (data) => {
            try {
                // 处理可能的多个消息
                const messages = data.toString().split('}{').map((msg, i, arr) => {
                    if (i === 0 && arr.length > 1) return msg + '}';
                    if (i === arr.length - 1 && arr.length > 1) return '{' + msg;
                    if (arr.length > 1) return '{' + msg + '}';
                    return msg;
                });
                
                messages.forEach(msgStr => {
                    try {
                        const message = JSON.parse(msgStr);
                        handleClientMessage(playerId, message);
                    } catch (e) {
                        // 忽略解析错误
                    }
                });
            } catch (e) {
                console.log('解析消息失败:', e.message);
            }
        });
        
        socket.on('close', () => {
            console.log(`玩家 ${playerId} 已断开`);
            if (players.has(playerId)) {
                players.get(playerId).connected = false;
            }
        });
        
        sendToClient(socket, {type: 'connected', playerId: playerId, serverTickRate: serverUpdateInterval});
    });
    
    server.listen(port, () => {
        console.log(`服务器启动在端口 ${port}`);
        isServer = true;
        gameMode = "server";
        initializeServerGame();
    });
}

function connectToServer(host = 'localhost', port = 3000) {
    client = net.createConnection(port, host);
    
    // 设置TCP无延迟
    client.setNoDelay(true);
    
    client.on('connect', () => {
        console.log('已连接到服务器');
        isClient = true;
        gameMode = "client";
    });
    
    client.on('data', (data) => {
        try {
            const message = JSON.parse(data.toString());
            handleServerMessage(message);
        } catch (e) {
            console.log('解析服务器消息失败:', e.message);
        }
    });
    
    client.on('close', () => {
        console.log('与服务器连接已断开');
        process.exit();
    });
}

function sendToClient(socket, message) {
    if (socket && !socket.destroyed) {
        try {
            socket.write(JSON.stringify(message));
        } catch (e) {
            // 忽略发送错误
        }
    }
}

function sendToServer(message) {
    if (client && !client.destroyed) {
        try {
            client.write(JSON.stringify(message));
        } catch (e) {
            // 忽略发送错误
        }
    }
}

function handleClientMessage(playerId, message) {
    switch (message.type) {
        case 'move':
            if (players.has(playerId)) {
                const player = players.get(playerId);
                const newDir = message.direction;
                if (isValidDirection(player.direction, newDir)) {
                    // 将输入加入缓冲区
                    player.inputBuffer.push({
                        direction: newDir,
                        timestamp: message.timestamp || Date.now()
                    });
                    player.lastInput = Date.now();
                    
                    // 立即应用最新输入
                    player.direction = newDir;
                    
                    // 快速响应客户端
                    sendToClient(player.socket, {
                        type: 'moveAck',
                        direction: newDir,
                        timestamp: message.timestamp,
                        serverTime: Date.now()
                    });
                }
            }
            break;
        case 'ping':
            if (players.has(playerId)) {
                const player = players.get(playerId);
                sendToClient(player.socket, {
                    type: 'pong',
                    clientTime: message.timestamp,
                    serverTime: Date.now()
                });
            }
            break;
    }
}

function handleServerMessage(message) {
    switch (message.type) {
        case 'connected':
            currentPlayerId = message.playerId;
            break;
        case 'gameState':
            updateClientGameState(message.gameState);
            break;
        case 'moveAck':
            // 服务器确认移动，更新本地预测
            if (players.has(currentPlayerId)) {
                const player = players.get(currentPlayerId);
                player.direction = message.direction;
            }
            break;
    }
}

function isValidDirection(current, next) {
    const opposites = {
        'up': 'down', 'down': 'up',
        'left': 'right', 'right': 'left'
    };
    return opposites[current] !== next;
}

function initializeServerGame() {
    players.set('server', {
        snake: [[10, 10]],
        direction: "right",
        color: playerColors[0],
        connected: true,
        isServer: true
    });
}

function broadcastGameState() {
    if (!isServer) return;
    
    const gameState = {
        timestamp: Date.now(),
        players: Array.from(players.entries()).map(([id, player]) => ({
            id: id,
            snake: player.snake,
            connected: player.connected,
            color: player.color,
            direction: player.direction
        })),
        food: food,
        obstacles: obstacles,
        gameOver: gameOver
    };
    
    players.forEach((player) => {
        if (player.socket && player.connected && !player.isServer) {
            sendToClient(player.socket, {type: 'gameState', gameState: gameState});
        }
    });
}

function updateClientGameState(gameState) {
    // 更新客户端游戏状态
    food = gameState.food;
    obstacles = gameState.obstacles;
    gameOver = gameState.gameOver;
    lastServerUpdate = Date.now();
    
    // 更新玩家状态，进行插值处理
    gameState.players.forEach(serverPlayer => {
        const existingPlayer = players.get(serverPlayer.id);
        
        if (serverPlayer.id === currentPlayerId) {
            // 对自己的蛇进行预测和校正
            const prediction = clientPrediction.get(serverPlayer.id);
            if (prediction && clientInterpolation) {
                // 如果预测和服务器状态差异过大，进行平滑校正
                const diff = calculateSnakeDiff(prediction, serverPlayer.snake);
                if (diff > 3) {
                    // 差异过大，直接使用服务器状态
                    players.set(serverPlayer.id, {
                        snake: serverPlayer.snake,
                        connected: serverPlayer.connected,
                        color: serverPlayer.color,
                        direction: existingPlayer ? existingPlayer.direction : "right",
                        serverSnake: serverPlayer.snake
                    });
                } else {
                    // 差异较小，保持预测
                    players.set(serverPlayer.id, {
                        snake: prediction,
                        connected: serverPlayer.connected,
                        color: serverPlayer.color,
                        direction: existingPlayer ? existingPlayer.direction : "right",
                        serverSnake: serverPlayer.snake
                    });
                }
            } else {
                players.set(serverPlayer.id, {
                    snake: serverPlayer.snake,
                    connected: serverPlayer.connected,
                    color: serverPlayer.color,
                    direction: existingPlayer ? existingPlayer.direction : "right",
                    serverSnake: serverPlayer.snake
                });
            }
        } else {
            // 其他玩家使用插值
            players.set(serverPlayer.id, {
                snake: serverPlayer.snake,
                connected: serverPlayer.connected,
                color: serverPlayer.color,
                direction: existingPlayer ? existingPlayer.direction : "right",
                serverSnake: serverPlayer.snake
            });
        }
    });
    
    // 移除已断开的玩家
    const serverPlayerIds = new Set(gameState.players.map(p => p.id));
    players.forEach((player, playerId) => {
        if (!serverPlayerIds.has(playerId)) {
            players.delete(playerId);
        }
    });
}

// 计算蛇位置差异
function calculateSnakeDiff(snake1, snake2) {
    if (!snake1 || !snake2 || snake1.length === 0 || snake2.length === 0) return 999;
    const head1 = snake1[0];
    const head2 = snake2[0];
    return Math.abs(head1[0] - head2[0]) + Math.abs(head1[1] - head2[1]);
}

// 清屏
function clearScreen() {
    console.clear();
}

// 生成障碍物
function spawnObstacles(count) {
    if (!count) {
        count = gameMode === "single" ? 15 : 25; // 联机模式更多障碍物
    }
    obstacles = [];
    while (obstacles.length < count) {
        let x = Math.floor(Math.random() * (rows - 2)) + 1;
        let y = Math.floor(Math.random() * (cols - 2)) + 1;
        let occupied = false;
        
        if (gameMode === "single") {
            // 单机模式 - 检查玩家蛇和AI蛇
            occupied = snake.some(([sx, sy]) => sx === x && sy === y) ||
                      aiSnake.some(([sx, sy]) => sx === x && sy === y);
        } else {
            // 网络模式 - 检查所有玩家
            players.forEach((player) => {
                if (player.connected && player.snake.some(([sx, sy]) => sx === x && sy === y)) {
                    occupied = true;
                }
            });
        }
        
        if (!occupied) {
            obstacles.push([x, y]);
        }
    }
}

// 生成单个障碍物
function spawnSingleObstacle() {
    let x, y;
    let occupied = true;
    
    while (occupied) {
        x = Math.floor(Math.random() * (rows - 2)) + 1;
        y = Math.floor(Math.random() * (cols - 2)) + 1;
        occupied = false;
        
        // 检查是否与现有障碍物重叠
        if (obstacles.some(([ox, oy]) => ox === x && oy === y)) {
            occupied = true;
            continue;
        }
        
        if (gameMode === "single") {
            // 单机模式
            if (snake.some(([sx, sy]) => sx === x && sy === y) ||
                aiSnake.some(([sx, sy]) => sx === x && sy === y)) {
                occupied = true;
            }
        } else {
            // 网络模式 - 检查所有玩家
            players.forEach((player) => {
                if (player.connected && player.snake.some(([sx, sy]) => sx === x && sy === y)) {
                    occupied = true;
                }
            });
        }
    }
    
    obstacles.push([x, y]);
}

// 生成食物
function spawnFood() {
    const maxFood = gameMode === "single" ? 5 : 12; // 联机模式更多食物
    while (food.length < maxFood) {
        let x, y, type;
        let occupied = true;
        
        while (occupied) {
            x = Math.floor(Math.random() * (rows - 2)) + 1;
            y = Math.floor(Math.random() * (cols - 2)) + 1;
            type = Math.random() < 0.2 ? "+" : "*"; // 20%加倍
            occupied = false;
            
            // 检查障碍物和现有食物
            if (obstacles.some(([ox, oy]) => ox === x && oy === y) ||
                food.some(([fx, fy]) => fx === x && fy === y)) {
                occupied = true;
                continue;
            }
            
            if (gameMode === "single") {
                // 单机模式
                if (snake.some(([sx, sy]) => sx === x && sy === y) ||
                    aiSnake.some(([sx, sy]) => sx === x && sy === y)) {
                    occupied = true;
                }
            } else {
                // 网络模式 - 检查所有玩家
                players.forEach((player) => {
                    if (player.connected && player.snake.some(([sx, sy]) => sx === x && sy === y)) {
                        occupied = true;
                    }
                });
            }
        }
        
        food.push([x, y, type]);
    }
}

// 渲染地图
function render() {
    clearScreen();
    let screen = Array.from({ length: rows }, () => Array.from({ length: cols }, () => " "));

    // 边界
    for (let x = 0; x < rows; x++) { screen[x][0] = screen[x][cols - 1] = "#"; }
    for (let y = 0; y < cols; y++) { screen[0][y] = screen[rows - 1][y] = "#"; }

    // 障碍物
    obstacles.forEach(([x, y]) => screen[x][y] = colors.red + "#" + colors.reset);

    if (gameMode === "single") {
        // 单机模式 - 原有逻辑
        snake.forEach(([x, y], i) => screen[x][y] = i === 0 ? colors.green + "@" + colors.reset : colors.green + "O" + colors.reset);
        aiSnake.forEach(([x, y], i) => screen[x][y] = i === 0 ? colors.magenta + "X" + colors.reset : colors.magenta + "x" + colors.reset);
    } else {
        // 网络模式 - 显示所有玩家
        let playerIndex = 0;
        const symbols = ["@", "X", "&", "%", "#", "□", "△", "◇"];
        
        // 按playerId排序确保一致的颜色分配
        const sortedPlayers = Array.from(players.entries()).sort(([idA], [idB]) => {
            // 服务器玩家总是第一个
            if (idA === 'server') return -1;
            if (idB === 'server') return 1;
            // 其他玩家按ID排序
            return idA.localeCompare(idB);
        });
        
        sortedPlayers.forEach(([playerId, player]) => {
            if (!player.connected) return;
            const symbol = symbols[playerIndex] || "O";
            const headSymbol = symbol;
            const bodySymbol = symbol.toLowerCase();
            
            // 优先使用创建时分配的颜色，否则按顺序分配
            const playerColor = player.color || playerColors[playerIndex % playerColors.length];
            
            player.snake.forEach(([x, y], i) => {
                screen[x][y] = i === 0 
                    ? playerColor + headSymbol + colors.reset 
                    : playerColor + bodySymbol + colors.reset;
            });
            playerIndex++;
        });
    }

    // 食物
    food.forEach(([fx, fy, ft]) => {
        screen[fx][fy] = ft === "*" ? colors.yellow + "*" + colors.reset : colors.cyan + "+" + colors.reset;
    });

    // 状态显示
    if (gameMode === "single") {
        console.log(`玩家:@ | AI:X | 分数 玩家:${snake.length - 1} AI:${aiSnake.length - 1} | 生命:${lives}`);
    } else {
        let statusText = `模式:${gameMode} | `;
        if (isServer) statusText += "服务器 | ";
        if (isClient) statusText += `客户端(${currentPlayerId}) | `;
        
        let playerStats = [];
        players.forEach((player, playerId) => {
            if (player.connected) {
                playerStats.push(`${playerId}:${player.snake.length - 1}`);
            }
        });
        statusText += playerStats.join(" | ");
        console.log(statusText);
    }
    
    console.log(screen.map((row) => row.join("")).join("\n"));
}

// 移动函数
function moveSnake(snakeArr, dir) {
    const [dx, dy] = directions[dir];
    let [hx, hy] = snakeArr[0];
    let newHead = [hx + dx, hy + dy];

    if (wrapAround) {
        if (newHead[0] <= 0) newHead[0] = rows - 2;
        if (newHead[0] >= rows - 1) newHead[0] = 1;
        if (newHead[1] <= 0) newHead[1] = cols - 2;
        if (newHead[1] >= cols - 1) newHead[1] = 1;
    }

    return newHead;
}

// AI蛇移动
function moveAISnake() {
    if (aiSnake.length === 0 || food.length === 0) return;

    let [hx, hy] = aiSnake[0];

    // 找最近食物
    let targetFood = food.reduce((a, b) => {
        let d1 = Math.abs(a[0]-hx)+Math.abs(a[1]-hy);
        let d2 = Math.abs(b[0]-hx)+Math.abs(b[1]-hy);
        return d1 <= d2 ? a : b;
    });
    let [fx, fy, ft] = targetFood;

    // 决定方向
    let possibleDirs = [];
    if (fx < hx) possibleDirs.push("up");
    else if (fx > hx) possibleDirs.push("down");
    if (fy < hy) possibleDirs.push("left");
    else if (fy > hy) possibleDirs.push("right");

    let newHead;
    for (let d of possibleDirs) {
        newHead = moveSnake(aiSnake, d);
        if (!obstacles.some(([ox, oy]) => ox === newHead[0] && oy === newHead[1]) &&
            !aiSnake.some(([sx, sy]) => sx === newHead[0] && sy === newHead[1])) {
            aiDirection = d;
            break;
        }
    }

    if (!newHead || obstacles.some(([ox, oy]) => ox === newHead[0] && oy === newHead[1]) ||
        aiSnake.some(([sx, sy]) => sx === newHead[0] && sy === newHead[1])) {
        const dirs = ["up","down","left","right"];
        for (let i=0;i<10;i++) {
            let d = dirs[Math.floor(Math.random()*4)];
            newHead = moveSnake(aiSnake,d);
            if (!obstacles.some(([ox, oy])=>ox===newHead[0]&&oy===newHead[1]) &&
                !aiSnake.some(([sx, sy])=>sx===newHead[0]&&sy===newHead[1])) {
                aiDirection = d;
                break;
            }
        }
    }

    // AI碰撞玩家蛇
    let hitPlayerSnake = snake.some(([x, y]) => x === newHead[0] && y === newHead[1]);
    if (hitPlayerSnake) {
        aiSnake.pop();
        if (aiSnake.length === 0) {
            aiSnake = [[Math.floor(Math.random()*(rows-2))+1, Math.floor(Math.random()*(cols-2))+1]];
        }
        newHead = aiSnake[0];
    }

    // 吃食物
    let ate = false;
    for (let i = food.length - 1; i >= 0; i--) {
        const f = food[i];
        if (!f) continue;
        const [fx2, fy2, ft2] = f;
        if (newHead && newHead[0] === fx2 && newHead[1] === fy2) {
            ate = true;
            if (ft2 === "*") aiSnake.unshift(newHead);
            else if (ft2 === "+") aiSnake.unshift(newHead, [...aiSnake[0]]);
            food.splice(i,1);
            break;
        }
    }

    if (!ate) {
        aiSnake.unshift(newHead);
        aiSnake.pop();
    }
}

// 客户端预测移动
function predictClientMovement() {
    if (!isClient) return;
    
    const player = players.get(currentPlayerId);
    if (!player || !player.connected || player.snake.length === 0) return;
    
    // 进行本地预测移动
    let predictedSnake = [...player.snake.map(segment => [...segment])];
    let newHead = moveSnake(predictedSnake, player.direction);
    
    // 简单的碰撞检测（不包括其他玩家）
    let hitSelf = predictedSnake.some(([x, y]) => x === newHead[0] && y === newHead[1]);
    let hitObstacle = obstacles.some(([x, y]) => x === newHead[0] && y === newHead[1]);
    let hitWall = !wrapAround && (newHead[0] <= 0 || newHead[0] >= rows - 1 || newHead[1] <= 0 || newHead[1] >= cols - 1);
    
    if (!hitSelf && !hitObstacle && !hitWall) {
        // 检查是否吃到食物
        let ate = false;
        for (let i = 0; i < food.length; i++) {
            const [fx, fy, ft] = food[i];
            if (newHead[0] === fx && newHead[1] === fy) {
                ate = true;
                if (ft === "*") {
                    predictedSnake.unshift(newHead);
                } else if (ft === "+") {
                    predictedSnake.unshift(newHead, [...predictedSnake[0]]);
                }
                break;
            }
        }
        
        if (!ate) {
            predictedSnake.unshift(newHead);
            predictedSnake.pop();
        }
        
        // 保存预测结果
        player.snake = predictedSnake;
        clientPrediction.set(currentPlayerId, predictedSnake);
    }
}

// 主循环
function move() {
    if (gameOver) return;

    if (gameMode === "single") {
        // 单机模式 - 原有逻辑
        let newHead = moveSnake(snake, direction);

        let hitSelf = snake.some(([x, y]) => x === newHead[0] && y === newHead[1]);
        let hitObstacle = obstacles.some(([x, y]) => x === newHead[0] && y === newHead[1]);
        let hitAISnake = aiSnake.some(([x, y]) => x === newHead[0] && y === newHead[1]);
        let hitWall = !wrapAround && (newHead[0] <=0 || newHead[0]>=rows-1 || newHead[1]<=0 || newHead[1]>=cols-1);

        if (hitWall) gameOver = true;

        if (hitObstacle) {
            lives--;
            if (lives <= 0) gameOver = true;
            else {
                newHead = snake[0];
                obstacles = obstacles.filter(([ox, oy]) => !(ox === newHead[0] && oy === newHead[1]));
                spawnSingleObstacle();
            }
        }

        if (hitSelf) {
            const index = snake.findIndex(([x, y]) => x === newHead[0] && y === newHead[1]);
            snake = snake.slice(0, index);
            lives--;
            if (lives <=0) gameOver = true;
            newHead = snake[0];
        }

        if (hitAISnake) {
            snake.pop();
            newHead = snake[0];
        }

        if (gameOver) {
            clearScreen();
            console.log("游戏结束! 你的得分: " + (snake.length-1));
            process.exit();
        }

        // 吃食物
        let ate = false;
        for (let i = food.length - 1; i >= 0; i--) {
            const f = food[i];
            if (!f) continue;
            const [fx, fy, ft] = f;
            if (newHead && newHead[0] === fx && newHead[1] === fy) {
                ate = true;
                if(ft === "*") snake.unshift(newHead);
                else if(ft === "+") snake.unshift(newHead,[...snake[0]]);
                food.splice(i,1);
                break;
            }
        }

        if (!ate && !hitObstacle && !hitSelf && !hitAISnake) {
            snake.unshift(newHead);
            snake.pop();
        }

        // AI移动
        moveAISnake();

        // 保持食物数量
        const maxFood = gameMode === "single" ? 5 : 12;
        if(food.length < maxFood) spawnFood();
    } else {
        // 网络模式
        if (isServer) {
            // 服务器使用固定的tick rate
            const now = Date.now();
            if (now - lastServerTick >= serverUpdateInterval) {
                moveAllPlayers();
                broadcastGameState();
                lastServerTick = now;
            }
        } else if (isClient) {
            // 客户端进行本地预测
            predictClientMovement();
        }
    }

    render();
    // 优化更新频率
    let updateInterval;
    if (isServer) {
        updateInterval = serverUpdateInterval; // 服务器使用固定的tick rate
    } else if (isClient) {
        updateInterval = 300; // 客户端高频率更新以实现流畅预测
    } else {
        updateInterval = speed; // 单机模式使用默认速度
    }
    setTimeout(move, updateInterval);
}

// 多玩家移动逻辑
function moveAllPlayers() {
    // 处理输入缓冲区
    players.forEach((player, playerId) => {
        if (player.inputBuffer && player.inputBuffer.length > 0) {
            // 应用最新的输入
            const latestInput = player.inputBuffer[player.inputBuffer.length - 1];
            player.direction = latestInput.direction;
            // 清空缓冲区
            player.inputBuffer = [];
        }
    });
    
    players.forEach((player, playerId) => {
        if (!player.connected || player.snake.length === 0) return;
        
        let newHead = moveSnake(player.snake, player.direction);
        
        // 碰撞检测
        let hitSelf = player.snake.some(([x, y]) => x === newHead[0] && y === newHead[1]);
        let hitObstacle = obstacles.some(([x, y]) => x === newHead[0] && y === newHead[1]);
        let hitWall = !wrapAround && (newHead[0] <=0 || newHead[0]>=rows-1 || newHead[1]<=0 || newHead[1]>=cols-1);
        
        // 检测与其他玩家碰撞
        let hitOtherPlayer = false;
        players.forEach((otherPlayer, otherPlayerId) => {
            if (otherPlayerId !== playerId && otherPlayer.connected) {
                if (otherPlayer.snake.some(([x, y]) => x === newHead[0] && y === newHead[1])) {
                    hitOtherPlayer = true;
                }
            }
        });

        if (hitWall) {
            // 撞墙后重新随机生成位置
            player.snake = [[Math.floor(Math.random()*(rows-2))+1, Math.floor(Math.random()*(cols-2))+1]];
            newHead = player.snake[0];
        }

        if (hitObstacle) {
            // 撞障碍物后变短并移除该障碍物
            player.snake.pop();
            if (player.snake.length === 0) {
                player.snake = [[Math.floor(Math.random()*(rows-2))+1, Math.floor(Math.random()*(cols-2))+1]];
            }
            obstacles = obstacles.filter(([ox, oy]) => !(ox === newHead[0] && oy === newHead[1]));
            spawnSingleObstacle();
            newHead = player.snake[0];
        }

        if (hitSelf) {
            // 撞到自己后截断到碰撞点
            const index = player.snake.findIndex(([x, y]) => x === newHead[0] && y === newHead[1]);
            player.snake = player.snake.slice(0, index);
            if (player.snake.length === 0) {
                player.snake = [[Math.floor(Math.random()*(rows-2))+1, Math.floor(Math.random()*(cols-2))+1]];
            }
            newHead = player.snake[0];
        }

        if (hitOtherPlayer) {
            player.snake.pop();
            if (player.snake.length === 0) {
                player.snake = [[Math.floor(Math.random()*(rows-2))+1, Math.floor(Math.random()*(cols-2))+1]];
            }
            newHead = player.snake[0];
        }

        // 吃食物
        let ate = false;
        for (let i = food.length - 1; i >= 0; i--) {
            const f = food[i];
            if (!f) continue;
            const [fx, fy, ft] = f;
            if (newHead && newHead[0] === fx && newHead[1] === fy) {
                ate = true;
                if(ft === "*") player.snake.unshift(newHead);
                else if(ft === "+") player.snake.unshift(newHead,[...player.snake[0]]);
                food.splice(i,1);
                break;
            }
        }

        if (!ate && !hitObstacle && !hitSelf && !hitOtherPlayer && !hitWall) {
            player.snake.unshift(newHead);
            player.snake.pop();
        }
    });
    
    // 保持食物数量  
    const maxFood = 12; // 网络模式固定12个食物
    if(food.length < maxFood) spawnFood();
}

// 设置键盘监听
function setupKeyboardListeners() {
    process.stdin.setRawMode(true);
    
    // 移除之前的监听器
    process.stdin.removeAllListeners('keypress');
    
    process.stdin.on("keypress", (_, key) => {
        if(key.ctrl && key.name === "c") process.exit();
        if(["up","down","left","right"].includes(key.name)){
            if (gameMode === "single") {
                // 单机模式
                if((direction==="up" && key.name!=="down") ||
                   (direction==="down" && key.name!=="up") ||
                   (direction==="left" && key.name!=="right") ||
                   (direction==="right" && key.name!=="left")){
                    direction = key.name;
                }
            } else if (gameMode === "server") {
                // 服务器模式 - 直接更新服务器玩家
                const serverPlayer = players.get('server');
                if (serverPlayer && isValidDirection(serverPlayer.direction, key.name)) {
                    serverPlayer.direction = key.name;
                }
            } else if (gameMode === "client") {
                // 客户端模式 - 本地立即更新并发送到服务器
                const player = players.get(currentPlayerId);
                if (player && isValidDirection(player.direction, key.name)) {
                    player.direction = key.name;
                    sendToServer({
                        type: 'move',
                        direction: key.name,
                        timestamp: Date.now()
                    });
                }
            }
        }
    });
}

// 游戏模式选择
function showMenu() {
    clearScreen();
    console.log("=== 贪吃蛇游戏 ===");
    console.log("选择游戏模式:");
    console.log("1. 单机模式 (玩家 vs AI)");
    console.log("2. 创建服务器 (局域网多人游戏)");
    console.log("3. 连接服务器 (加入游戏)");
    console.log("按对应数字键选择模式...");
    
    process.stdin.once('data', (data) => {
        const choice = data.toString().trim();
        switch (choice) {
            case '1':
                startSinglePlayerGame();
                break;
            case '2':
                startServerGame();
                break;
            case '3':
                startClientGame();
                break;
            default:
                console.log("无效选择，请重新选择...");
                setTimeout(showMenu, 1000);
        }
    });
}

// 单机游戏
function startSinglePlayerGame() {
    gameMode = "single";
    setupKeyboardListeners();
    clearScreen();
    console.log("贪吃蛇增强版 双蛇模式! 玩家:@ AI:X | Ctrl+C退出");
    spawnObstacles();
    spawnFood();
    render();
    move();
}

// 服务器游戏
function startServerGame() {
    console.log("请输入服务器端口 (默认3000):");
    process.stdin.once('data', (data) => {
        const port = parseInt(data.toString().trim()) || 3000;
        setupKeyboardListeners();
        createServer(port);
        console.log(`等待玩家连接... (端口: ${port})`);
        console.log("服务器创建后将开始游戏");
        console.log(`服务器更新频率: ${1000/serverUpdateInterval}Hz`);
        setTimeout(() => {
            spawnObstacles();
            spawnFood();
            render();
            move();
        }, 2000);
    });
}

// 客户端游戏
function startClientGame() {
    console.log("请输入服务器地址 (默认localhost:3000):");
    process.stdin.once('data', (data) => {
        const input = data.toString().trim();
        let host = 'localhost';
        let port = 3000;
        
        if (input) {
            const parts = input.split(':');
            host = parts[0] || 'localhost';
            port = parseInt(parts[1]) || 3000;
        }
        
        console.log(`正在连接到 ${host}:${port}...`);
        setupKeyboardListeners();
        connectToServer(host, port);
        
        setTimeout(() => {
            render();
            move();
        }, 1000);
    });
}

// 启动游戏
if (require.main === module) {
    // 初始化键盘事件
    readline.emitKeypressEvents(process.stdin);
    // 设置原始模式用于菜单选择
    process.stdin.setRawMode(false);
    showMenu();
}